package com.baidu.process.imchat;

import javax.annotation.PostConstruct;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.InvalidKeyException;
import java.security.Timestamp;
import java.util.Date;
import java.util.UUID;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Locale;
import java.util.TimeZone;

import com.baidu.process.chat.core.web.bean.IMRequestServer;
import org.apache.commons.codec.binary.Base64;

public class HmacGeneratorDemo {
    public final static String RFC1123_PATTERN = "EEE, dd MMM yyyy HH:mm:ss z";
    public final static Locale LOCALE_US = Locale.US;
    public final static DateFormat rfc1123Format = new SimpleDateFormat(RFC1123_PATTERN, LOCALE_US);
    public final static TimeZone GMT_ZONE = TimeZone.getTimeZone("GMT+00:00");
    static {
        rfc1123Format.setTimeZone(GMT_ZONE);
    }
    public static String sign(String secret, String stringToSign) {
        try{
            Mac hmacSha256 = Mac.getInstance("HmacSHA256");
            byte[] secretBytes = secret.getBytes("UTF-8");
            hmacSha256.init(new SecretKeySpec(secretBytes, 0, secretBytes.length, "HmacSHA256"));
            byte[] result = hmacSha256.doFinal(stringToSign.getBytes("UTF-8"));
            return Base64.encodeBase64String(result);
        } catch (NoSuchAlgorithmException | InvalidKeyException | UnsupportedEncodingException e) {
            throw new IllegalArgumentException("签名错误:" + e.getMessage());
        }
    }
    static final byte hexDigitsLower[] = { '0', '1', '2', '3', '4', '5', '6', '7','8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
    public static byte[] MD5(byte[] plainText) {
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");

            mdTemp.update(plainText);

            return mdTemp.digest();
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * GET请求demo
     * @version 1.0.0
     * @date 2022/10/20 09:39
     * @param
     * @return void
     */
    public static void generateGetRequest(){
        Date currentDate = new Date();

        /** 需要请求头传的值 start (定义参与签名的字段，需要请求头传x-ca-signature-headers：x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method) */
        String x_ca_key = "204114990";
        String Accept = "application/json; charset=UTF-8";  // 需要定义 避免取浏览器的默认值 造成签名失败
        String x_ca_signature_method = "HmacSHA256";
        String date = rfc1123Format.format(currentDate);
        String x_ca_nonce = UUID.randomUUID().toString();
        String x_ca_timestamp = String.valueOf(currentDate.getTime());
        /** 需要请求头传的值 end */

        String ContentMD5 = ""; // Content-MD5：请求中的Content-MD5头的值，可为空只有在请求存在Body且Body为非Form形式时才计算Content-MD5头
        String ContentType = ""; // 请求中的Content-Type头的值，可为空

        /** 根据请求获取 */
        String HTTPMethod = "GET";
        String PathAndParameters = "/mid-end-im-bridge/v1/member/1";

        String stringToSign = HTTPMethod + "\n" + Accept + "\n" + ContentMD5 + "\n" + ContentType + "\n"
                + date + "\n" + "x-ca-key:" + x_ca_key + "\n" + "x-ca-nonce:" + x_ca_nonce + "\n"
                + "x-ca-signature-method:" + x_ca_signature_method + "\n"
                + "x-ca-timestamp:" + x_ca_timestamp + "\n" + PathAndParameters;
        System.out.println(stringToSign);

        String secret = "bjGqb3TvEEZ8W8QhoyhEH4IenwCnc4JQ";
        String sign = sign(secret, stringToSign);
        System.out.println(sign);
    }

    public static String generateWithRequestBody(String bodyStream, Date currentDate, IMRequestServer imRequestServer){

        /** 需要请求头传的值 start (定义参与签名的字段，需要请求头传x-ca-signature-headers：x-ca-timestamp,x-ca-key,x-ca-nonce,x-ca-signature-method) */
        String x_ca_key = "204114990";
        String x_ca_signature_method = "HmacSHA256";
        String x_ca_nonce = imRequestServer.getSessionId();
        String x_ca_timestamp = String.valueOf(currentDate.getTime());
        String date = rfc1123Format.format(currentDate);
        String accept = "application/json; charset=UTF-8";  // 需要定义 避免取浏览器的默认值 造成签名失败
        /**
         * 请求中的Content-MD5头的值，可为空只有在请求存在Body且Body为非Form形式时才计算Content-MD5头，下面是Java的Content-MD5值的参考计算方式
         * String content-MD5 = Base64.encodeBase64(MD5(bodyStream.getbytes("UTF-8")));
         */
        String contentMD5 = new String(Base64.encodeBase64(MD5(bodyStream.getBytes(StandardCharsets.UTF_8))));
        System.out.println(contentMD5);
        /** 需要请求头传的值 end */

        String HTTPMethod = "POST";
        String PathAndParameters = "/mid-end-im-bridge/v1/msg";
        String ContentType = "application/json";

        String stringToSign = HTTPMethod + "\n" + accept + "\n" + contentMD5 +"\n" + ContentType + "\n"
                + date + "\n" + "x-ca-key:" + x_ca_key + "\n" + "x-ca-nonce:" + x_ca_nonce + "\n"
                + "x-ca-signature-method:" + x_ca_signature_method + "\n"
                + "x-ca-timestamp:" + x_ca_timestamp + "\n" + PathAndParameters;
        System.out.println(stringToSign);

        String secret = "bjGqb3TvEEZ8W8QhoyhEH4IenwCnc4JQ";
        String sign = sign(secret, stringToSign);
        System.out.println(sign);
        return sign;
    }

    public static void main(String[] args) throws IOException {
        String str = "adbcdaaaeee";
        System.out.println(str.replaceAll("a","x"));



    }


}
